<?php

namespace app\controller;

use app\BaseController;
use Exception;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\response\Json;

class Mod extends BaseController
{
    /**
     * 保存MOD(发布MOD/编辑MOD)
     */
    public function add(): Json
    {
        $uid = $this->getUid();
        $api_version = request()->post('api_version');//支持api列表
        $cover_src = request()->post('cover');//封面src
        $package_id = request()->post('package_id');//模组唯一标识ID
        $desc = request()->post('desc');//介绍
        $name = request()->post('name');//名称
        $en_name = request()->post('en_name');//名称
        $mini_name = request()->post('mini_name');//名称
        $game_version = request()->post('game_version');//支持游戏主体列表
        $mod_author = request()->post('mod_author');//作者列表
        $flag = request()->post('flag');//标签列表
        $link = request()->post('link');//连接列表
        $relation = request()->post('relation');//关系列表
        $modId = request()->post('id');//ModId
        if (empty($name)) {
            return pr(300, "参数不完整");
        }
        if (empty($uid)) {
            return pr(300, "请先登录");
        }
        $flag = json_decode($flag,true);
        $link = json_decode($link,true);
        $relation = json_decode($relation,true);
        $api_version = json_decode($api_version,true);
        $game_version = json_decode($game_version,true);
        $mod_author = json_decode($mod_author,true);
        $this->startTrans();
        try {
            //$check = $this->M("mod")->field('id')->where('uid','=',$uid)->where('package_id','=',$package_id)->where('name','=',$name)->find();
            if(!empty($check)){
                throw new Exception('模组已存在，重复创建');
            }
            $data = [
                'uid' => $uid,
                'name' => $name,
                'en_name'=>$en_name,
                'mini_name'=>$mini_name,
                'description' => $desc,
                'cover_src' => $cover_src,
                'package_id' => $package_id,
                'create_time' => time(),
                'last_modify_time' => time()
            ];
            if($modId > 0) $this->M("mod")->where('id','=',$modId)->save($data);
            else $modId = $this->M("mod")->insert($data,true);

            $flagList = [];
            //标签列表
            foreach ($flag as $v){
                $flagList[] = ['mod_id'=>$modId,'flag_id'=>$v];
            }
            if($modId > 0 ){
                $this->M('mod_flag_detail')->where('mod_id','=',$modId)->delete();
                $this->M('mod_api_detail')->where('mod_id','=',$modId)->delete();
                $this->M('mod_game_detail')->where('mod_id','=',$modId)->delete();
                $this->M('mod_server_detail')->where('mod_id','=',$modId)->delete();
                $this->M('mod_author')->where('mod_id','=',$modId)->delete();
                $this->M('mod_link_detail')->where('mod_id','=',$modId)->delete();
                $list = $this->M('mod_relate')->field('id')->where('mod_id','=',$modId)->select()->toArray();
                foreach ($list as $v) $this->M('mod_relate_detail')->where('relate_id','=',$v['id'])->delete();
                $this->M('mod_relate')->where('mod_id','=',$modId)->delete();
            }
            $this->M('mod_flag_detail')->insertAll($flagList);
            $apiList = [];
            //API版本列表
            foreach ($api_version as $v){
                $apiList[] = ['mod_id'=>$modId,'version_id'=>$v];
            }
            $this->M('mod_api_detail')->insertAll($apiList);
            $gameList = [];
            //游戏主体版本列表
            foreach ($game_version as $v){
                $gameList[] = ['mod_id'=>$modId,'version_id'=>$v];
            }
            $this->M('mod_game_detail')->insertAll($gameList);
            //作者列表
            $gameList = [];
            foreach ($mod_author as $v){
                $gameList[] = ['mod_id'=>$modId,'staff'=>$v['staff'],'uid'=>$v['uid']];
            }
            $this->M('mod_author')->insertAll($gameList);
            $linkList = [];
            //链接列表
            foreach ($link as $v){
                $linkList[] = ['mod_id'=>$modId,'src'=>$v['src'],'link_type'=>$v['type']];
            }
            $this->M('mod_link_detail')->insertAll($linkList);
            //Mod关系列表
            foreach ($relation as $v){
                $relationId = $this->M("mod_relate")->insert(['mod_id'=>$modId,'condition_value'=>$v['condition']],true);
                $itemList=[];
                foreach ($v['list'] as $vv){
                    $itemList[] = ['relate_id'=>$relationId,'relate_mod_id'=>$vv['package_id'],'relate_type'=>$vv['type']];
                }
                $this->M('mod_relate_detail')->insertAll($itemList);
            }
            $this->commit();
            return pr(200, "保存成功");
        } catch (Exception $e) {
            $this->rollback();
            return pr(300, "保存失败", $e->getMessage());
        }
    }
    /**
     * 获取MOD列表
     */
    public function list(): Json
    {
        $page = request()->post('page',1,'int');
        $limit = request()->post('limit',10,'int');
        $search = request()->post('search');
        $cate_filter = request()->post('cate_filter',0,'int');//分类过滤
        $flag_filter = request()->post('flag_filter',0,'int');//标签过滤
        try {
            $obj = $this->M("mod")
                ->alias('m')
                ->field("m.id,m.name,m.en_name,m.mini_name,m.downloads,m.likes,m.views,m.description,group_concat(mfd.flag_id) as flag_list,m.cover_src,m.create_time,m.last_modify_time")
                ->where('m.stat','=',1);
            if (!empty($search)) {
                $obj->where("m.name", "like", "%" . $search . "%");
            }
            if(!empty($cate_filter)){
                $obj->join("mod_file mf","mf.mod_id = m.id");
                if($cate_filter != 5) {
                    $obj->join("document d","d.id = mf.document_id");
                    $obj->where("mf.document_id",'>',0);
                    $obj->where("d.file_type",'=',$cate_filter);
                }
                else {
                    $obj->where("mf.document_id",'=',0);
                }
            }
            $mfdFilter = 'mfd.mod_id = m.id ';
            if (!empty($flag_filter)) {
                $obj->where('mfd.flag_id','=',$flag_filter);
            }
            $obj->leftJoin('mod_flag_detail mfd',$mfdFilter);
            $obj->group("m.id")->order('m.last_modify_time','desc');
            $flagCount = 0;
            $flagSum = [];
            $cateSum = [];
            if($page==1){
                $flagCount = $obj->count();
                //按照mod文件类型进行分类计数
                $subQuery = $this->M('mod')
                    ->alias('m')
                    ->field('m.id,mf.document_id')
                    ->join("mod_file mf","mf.mod_id = m.id")
                    ->where("m.stat",'=',1)
                    ->group("m.id,mf.document_id")
                    ->buildSql();
                $subQuery = $this->M('('.$subQuery.') t',false)
                    ->field('ifnull(d.file_type,5) as file_type,t.id')
                    ->leftJoin('document d','d.id = t.document_id')
                    ->group('d.file_type,t.id')
                    ->buildSql();
                $cateSum = $this->M('('.$subQuery.') t2',false)
                    ->field('t2.file_type,count(t2.id) as count')
                    ->group('t2.file_type')
                    ->select()->toArray();
                //按照mod标签进行分类计数
                $subQuery = $this->M('mod')
                    ->alias('m')
                    ->field('m.id')
                    ->where("m.stat",'=',1)
                    ->buildSql();
                $subQuery = $this->M('('.$subQuery.') t',false)
                    ->field('t.id,ifnull(mfd.flag_id,-1) as flag_id')//-1表示没有标签的??
                    ->leftJoin('mod_flag_detail mfd','mfd.mod_id = mfd.t.id')
                    ->group('t.id,mfd.flag_id')
                    ->buildSql();
                $flagSum = $this->M('('.$subQuery.') t2',false)
                    ->field('count(t2.id) as count,t2.flag_id')
                    ->group('t2.flag_id')
                    ->select()
                    ->toArray();
                $fid = [];
                foreach ($flagSum as $v) $fid[] = $v['flag_id'];
                $mlf = $this->M('mod_flag_list')->field('id as flag_id')->where('id','not in',$fid)->select();
                foreach ($mlf as $v){
                    $flagSum[] = ['count'=>0,'flag_id'=>$v['flag_id']];
                }
                array_unshift($flagSum,['flag_id'=>0,'count'=>$flagCount]);
            }
            $cateCount = 0;
            foreach ($cateSum as $v) $cateCount+=$v['count'];
            array_unshift($cateSum,['file_type'=>0,'count'=>$cateCount]);
            $data = $obj->page($page,$limit)
                ->select();
            $data['_extra'] = ['sum' => ['total' => $flagCount],'flag_sum'=>$flagSum,'cate_sum'=>$cateSum];
            return pr(200, "获取成功", $data);
        } catch (Exception $e) {
            return pr(300, "获取失败" . $e->getMessage());
        }
    }
    public function ready_publish(){
        $id = request()->post('id',0,'int');
        $uid = $this->getUid();
        if(empty($id)) return json(300,'参数错误');
        if(empty($uid)) return json(300,API_NEED_LOGIN);
        else{
            $r = $this->M('mod')->where('uid','=',$uid)->where('id','=',$id)->save(['stat'=>2]);
            if($r) return pr(200);
            else pr(300);
        }
    }
    public function item($id): Json
    {
        try {
            $fields=[];
            $fields[]='m.id,m.package_id,m.rate,m.name,m.en_name,m.mini_name,m.downloads,m.likes,m.views,m.description,m.cover_src,m.create_time,m.last_modify_time';
            $fields[]='group_concat(mfd.flag_id) as flag_list';

            $obj = $this->M("mod")
                ->alias('m')
                ->field(implode(',',$fields));
            $mfdFilter = 'mfd.mod_id = m.id ';
            if (!empty($flag_filter)) {
                $mfdFilter.=' and mfd.id = '.$flag_filter;
            }
            $obj->leftJoin('mod_flag_detail mfd',$mfdFilter);
            $subQuery = $obj->where('m.id','=',$id)->group("m.id")->buildSql();
            //获取相关链接列表
            $fields =[];
            $fields[]='tb.*';
            $fields[]='group_concat(mld.link_type,\',\',mld.src SEPARATOR \'|\') as link_list';
            $subQuery = $this->M('('.$subQuery.') tb',false)
                ->field(implode(',',$fields))
                ->leftJoin('mod_link_detail mld','mld.mod_id = tb.id')
                ->group("tb.id")
                ->buildSql();
            //获取游戏版本列表
            $fields =[];
            $fields[]='t.*';
            $fields[]='group_concat(mgd.version_id) as game_list';
            $subQuery = $this->M('('.$subQuery.') t',false)
                ->field(implode(',',$fields))
                ->leftJoin('mod_game_detail mgd','mgd.mod_id = t.id')
                ->group("t.id")
                ->buildSql();
            //获取API列表
            $fields =[];
            $fields[]='group_concat(mad.version_id) as api_list';
            $fields[]='t2.*';
            $data = $this->M('('.$subQuery.') t2',false)
                ->field(implode(',',$fields))
                ->leftJoin('mod_api_detail mad','mad.mod_id = t2.id')
                ->group("t2.id")
                ->select()
                ->toArray();
            //获取关系列表
            $fields=[];
            $fields[]='mr.condition_value,mr.id,group_concat(mrd.relate_type,\',\',m.name,\',\',mrd.relate_mod_id SEPARATOR \'|\') as relation';
            $obj = $this->M("mod_relate")
                ->alias('mr')
                ->field(implode(',',$fields))
                ->leftJoin('mod_relate_detail mrd','mrd.relate_id = mr.id')
                ->leftJoin('mod m','m.id = mrd.relate_mod_id');
            $data2 = $obj->where('mr.mod_id','=',$id)
                ->group("mr.id")
                ->select()
                ->toArray();
            $data3 = $this->M('mod_file')
                ->alias('mf')
                ->field('mf.description,mf.version,mf.create_time,f.size,f.name,f.down_times as downloads,f.id')
                ->join('files f','f.id = mf.file_id')
                ->where('mf.mod_id','=',$id)
                ->group("mf.id")
                ->page(1,5)
                ->select()
                ->toArray();
            //获取作者列表
            $data4 = $this->M('mod_author')
                ->alias('ma')
                ->field('u.id as uid,ma.staff,u.head_img as avatar,u.nickname')
                ->join('user u','u.id = ma.uid')
                ->where('ma.mod_id','=',$id)
                ->group("ma.id")
                ->select()
                ->toArray();
            //获取服务器地址列表
            $data5 = $this->M("mod_server_detail")
                ->alias('msd')
                ->field("msd.name,msd.ip_addr as ip,msd.create_time,svl.version")
                ->join("server_version_list svl",'svl.id = msd.version_id')
                ->where('msd.mod_id','=',$id)
                ->group("msd.id,svl.version")
                ->select()
                ->toArray();
            if(count($data)>0){
                $this->M('mod')->where('id','=',$id)->setInc('views');
                return pr(200,API_SUCCESS,['mod'=>$data[0],'relation'=>$data2,'version_list'=>$data3,'author_list'=>$data4,'server_list'=>$data5]);
            }else return pr(300,'获取失败');
        }catch (Exception $e){
            return pr(300,API_FAIL,$e->getMessage());
        }
    }
    public function version_list($id): Json
    {
        $page = request()->post('page',1,'int');
        $limit = request()->post('limit',10,'int');
        $count = 0;
        if($page==1){
            $count = $this->M('mod_file')->where('mod_id','=',$id)->count();
        }
        $data3 = $this->M('mod_file')
            ->alias('mf')
            ->field('mf.description,mf.version,mf.create_time,f.size,f.name,f.down_times as downloads,f.id')
            ->join('files f','f.id = mf.file_id')
            ->where('mf.mod_id','=',$id)
            ->group("mf.id")
            ->page($page,$limit)
            ->order('mf.create_time','desc')
            ->select()
            ->toArray();
        $data3['_extra'] = ['count'=>$count];
        return pr(200,'suc',$data3);
        
    }
    /**
     * 删除MOD
     */
    public function delete($id): Json
    {
        $uid = $this->getUid();
        $type = request()->post('type',0);//0软删除 1硬删除
        if (empty($id)) {
            return pr(300, "参数不完整");
        }
        try {
            $info = $this->M('mod')->field('uid')->where('id','=',$id)->find();
            if($info['uid']!=$uid){
                return pr(300,'你没有权限删除该Mod');
            }
            $rl = $this->M("mod_relate")->where(['mod_id' => $id])->field('id')->select()->toArray();
            $rld = [];
            foreach ($rl as $v){
                $rld[] = $v['id'];
            }
            if($type == 0){
                $this->M("mod")->where('id','=',$id)->update(['stat'=>0]);
            }else{
                $this->M("mod_api_detail")->where(['mod_id' => $id])->delete();
                $this->M("mod_game_detail")->where(['mod_id' => $id])->delete();
                $this->M("mod_relate")->where(['mod_id' => $id])->delete();
                $this->M("mod_relate_detail")->where('relate_id','in',$rld)->delete();
                $this->M("mod_flag_detail")->where(['mod_id' => $id])->delete();
                $this->M("mod_link_detail")->where(['mod_id' => $id])->delete();
                $this->M("mod")->where('id','=',$id)->delete();
            }
            return pr(200, "删除成功");
        } catch (Exception $e) {
            return pr(300, "删除失败" . $e->getMessage());
        }
    }

    /**
     * 获取文件列表
     * @param $id
     * @return Json
     */
    public function file_list($id):Json
    {
        try {
            $page = $this->request->post('page',1,'int');
            $limit = $this->request->post('limit',10,'int');
            $sum = 0;
            $obj = $this->M('mod_file')
                ->alias('mf')
                ->field('mf.id,mf.version,mf.description,mf.api_type,f.size,f.name,f.create_time,f.down_times as downloads')
                ->join('files f','f.id = mf.file_id')
                ->where('mf.mod_id', '=', $id)
                ->group("mf.id");
            if($page == 1) $sum = $obj->count();
            $list = $obj->page($page,$limit)->select()->toArray();
            $list['_extra'] = ['sum'=>$sum];
            return pr(200,API_SUCCESS,$list);
        } catch (DataNotFoundException|ModelNotFoundException|DbException $e) {
            return pr(300,API_FAIL,$e->getMessage());
        }
    }

    /**
     * 添加文件
     * @return Json
     */
    public function add_file():Json
    {
        $uid = $this->getUid();
        $version = request()->post('version');
        $file_id = request()->post('file_id',0,'int');
        $desc = request()->post('desc');
        $mod_id = request()->post('mod_id',0,'int');
        $rate = request()->post('rate',0,'float');
        $document_id = request()->post('document_id',0,'int');
        $api_type = request()->post('api_type',0,'int');
        if(empty($api_type)) return pr(300,'请选择API版本');
        if(empty($file_id)) return pr(300,'请先上传文件');
        try {
            $f = $this->M('mod')->field('uid')->where('id', '=', $mod_id)->find();
            if($f['uid']!=$uid) return pr(302,'没有此Mod添加权限');
        } catch (DataNotFoundException $e) {
            return pr(301,'不存在的Mod');
        } catch (ModelNotFoundException|DbException $e) {
            return pr(303,'SQL内部错误');
        }
        try {
            $f = $this->M('files')->field('uid')->where('id', '=', $file_id)->find();
            if($f['uid']!=$uid) return pr(302,'没有此文件使用权限');
        } catch (DataNotFoundException $e) {
            return pr(301,'不存在的文件ID');
        } catch (ModelNotFoundException|DbException $e) {
            return pr(303,'SQL内部错误');
        }
        $this->M('mod_file')->insert(['document_id'=>$document_id,'create_time'=>time(),'last_modify_time'=>time(),'version'=>$version,'mod_id'=>$mod_id,'file_id'=>$file_id,'api_type'=>$api_type,'description'=>$desc,'rate'=>$rate]);
        return pr(200,'添加文件成功');
    }

    /**
     * 删除文件
     * @param $id
     * @return Json
     */
    public function delete_file($id):Json
    {
        $uid = $this->getUid();
        if(empty($id)) return pr(300,'参数错误');
        try {
            $f = $this->M('mod_file')->field('mod_id,file_id')->where('id', '=', $id)->find();
            $m = $this->M('mod')->field('uid')->where('id','=',$f['mod_id'])->find();
        } catch (DataNotFoundException $e) {
            return pr(301,'不存在的Mod文件');
        } catch (ModelNotFoundException|DbException $e) {
            return pr(303,'SQL内部错误');
        }
        if($uid != $m['uid']) return pr(300,'你没有操作此文件的权限');
        try {
            $ff = $this->M('files')->field('path')->where('id', '=', $f['file_id'])->find();
            if(file_exists($ff['path'])){
                if(unlink($ff['path'])){
                    $this->M('mod_file')->where('id','=',$id)->delete();
                    $this->M('files')->where('id','=',$f['file_id'])->delete();
                    return pr(200,'删除成功');
                }
            }else{
                $this->M('mod_file')->where('id','=',$id)->delete();
                $this->M('files')->where('id','=',$f['file_id'])->delete();
                return pr(200,'删除成功');
            }
        } catch (DataNotFoundException|ModelNotFoundException|DbException $e) {
            return pr(300,'不存在的文件');
        }
        return pr(200,'添加文件成功');
    }
    public function server_list($id): Json
    {
        $list = $this->M('mod_server_detail')->field("msd.*,svl.version")->alias('msd')->join('server_version_list svl','svl.id = msd.version_id')->where('msd.mod_id','=',$id)->group('msd.id')->select()->toArray();
        return pr(200,$list);
    }
    public function add_server(): Json
    {
        $versionId = request()->post('version_id',0,'int');
        $ipAddress = request()->post('ip_addr');
        $modId = request()->post('mod_id',0,'int');
        $id = request()->post('id',0,'int');
        $name = request()->post('name');
        if(empty($id)){//添加
            $level = ($this->CheckAuthority($this->getUid(), "服列表管理")) ? 1 : 0;
            $this->M('mod_server_detail')->insert(['name'=>$name,'create_time'=>time(),'last_modify_time'=>time(),'mod_id'=>$modId,'version_id'=>$versionId,'ip_addr'=>$ipAddress,'level'=>$level]);
        }else{//修改
            $this->M('mod_server_detail')->where('id','=',$id)->save(['name'=>$name,'last_modify_time'=>time(),'mod_id'=>$modId,'version_id'=>$versionId,'ip_addr'=>$ipAddress]);
        }
        return pr(200);
    }
    public function delete_server($id): Json
    {
        if(empty($id)) return pr(300,'参数不能为空');
        try {
            $this->M('mod_server_detail')->where('id', '=', $id)->delete();
            return pr(200);
        } catch (DbException $e) {
            return pr(300,$e->getMessage());
        }
    }
    public function search_user(): Json
    {
        try {
            $key = $this->request->post('key');
            $obj = $this->M("user")->field("nickname,head_img as avatar,id");
            if(!empty($key)) $obj->where('nickname', 'like', '%' . $key . '%');
            $list = $obj->limit(0, 20)->select()->toArray();
            return pr(200,$list);
        } catch (DataNotFoundException|ModelNotFoundException|DbException $e) {
            return pr(300);
        }
    }
    public function global_data_list(): Json
    {
        $gameVersion = $this->M('game_version_list')->select()->toArray();
        $apiVersion = $this->M('api_version_list')->select()->toArray();
        $relateType = $this->M('mod_relate_type')->select()->toArray();
        $linkType = $this->M('mod_link_type')->select()->toArray();
        $flagList = $this->M('mod_flag_list')->select()->toArray();
        $serverVersionList = $this->M('server_version_list')->select()->toArray();
        return pr(200,API_SUCCESS,['game_version'=>$gameVersion,'api_version'=>$apiVersion,'relate_type'=>$relateType,'link_type'=>$linkType,'flag_list'=>$flagList,'server_version_list'=>$serverVersionList]);
    }
    
   
    private function CheckAuthority($uid, $type): bool
     {
        if (empty($uid)) return false;
        try {
            $roleList = $this->M('user_role')->where('uid', '=', $uid)->select()->toArray();
            if (empty($roleList)) return false;
            foreach($roleList as $v){
                if($v["role_id"] == 1 || $v["role_id"] == 2) return true;
                switch($type){
                    case "服列表管理": if($v["role_id"] == 16) return true; break;
                }
            }
            return false;
        } catch (DataNotFoundException | ModelNotFoundException | DbException $e) {
            return false;
        }
     }
    
    public function addReview(){
        $uid = $this->getUid();
        if(empty($uid)) return pr(300,'请先登录');
        
    }

}